package com.slofzx.nuoda.evaluation.version.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.slofzx.nuoda.common.exception.ServiceException;
import com.slofzx.nuoda.evaluation.enums.ComputeVersionTypeEnum;
import com.slofzx.nuoda.evaluation.version.dao.ProjectReportVersionDAO;
import com.slofzx.nuoda.evaluation.version.dto.ComputeVersionDTO;
import com.slofzx.nuoda.evaluation.version.dto.ProjectReportVersionDTO;
import com.slofzx.nuoda.evaluation.version.dto.ProjectReportVersionQueryDTO;
import com.slofzx.nuoda.evaluation.version.vo.ProjectReportVersionVO;
import com.slofzx.nuoda.evaluation.project.dao.ProjectInfoDAO;
import com.slofzx.nuoda.evaluation.project.entity.ProjectInfo;
import com.slofzx.nuoda.evaluation.project.enums.ProjectStateEnum;
import com.slofzx.nuoda.evaluation.project.enums.ReportAuditResultEnum;
import com.slofzx.nuoda.evaluation.project.observer.ProjectObserver;
import com.slofzx.nuoda.evaluation.version.service.ComputeVersionService;
import com.slofzx.nuoda.evaluation.version.entity.ProjectReportVersion;
import com.slofzx.nuoda.evaluation.version.service.ProjectReportVersionService;
import com.slofzx.nuoda.evaluation.version.vo.ComputeVersionVO;
import org.springframework.beans.factory.annotation.Autowired;
import com.slofzx.nuoda.common.enums.CommonResultEnum;
import com.slofzx.nuoda.common.enums.ServiceResult;
import com.slofzx.nuoda.common.service.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 评价信息服务实现类
 *
 * @author nuoda
 * @since 2022-08-11 08:55:59
 */
@Service("projectReportVersionService")
public class ProjectReportVersionServiceImpl extends BaseServiceImpl implements ProjectReportVersionService, ProjectObserver {
    @Resource
    private ProjectReportVersionDAO projectReportVersionDAO;

    @Resource
    private ProjectInfoDAO projectInfoDAO;

    @Autowired
    protected ComputeVersionService computeVersionService;

    /**
     * 将数据表数据转换为返回数据类型
     *
     * @param entity 数据表对应类
     * @return 实例对象
     */
    protected ProjectReportVersionVO parseEntity2VO(ProjectReportVersion entity) {
        ProjectReportVersionVO vo = new ProjectReportVersionVO();
        vo.setId(entity.getId());
        vo.setName(entity.getName());
        vo.setProjectId(entity.getProjectId());
        vo.setComputeVersion(entity.getComputeVersion());
        vo.setModelId(entity.getModelId());
        vo.setBuildYearCount(entity.getBuildYearCount());
        vo.setCalculateYearStart(entity.getCalculateYearStart());
        vo.setCalculateYearEnd(entity.getCalculateYearEnd());
        vo.setRemark(entity.getRemark());
        vo.setIrrBeforeTax(entity.getIrrBeforeTax());
        vo.setIrrAfterTax(entity.getIrrAfterTax());
        vo.setPbpBeforeTax(entity.getPbpBeforeTax());
        vo.setPbpAfterTax(entity.getPbpAfterTax());
        vo.setNpvBeforeTax(entity.getNpvBeforeTax());
        vo.setNpvAfterTax(entity.getNpvAfterTax());
        vo.setCreateUser(entity.getCreateUser());
        vo.setCreateTime(entity.getCreateTime());
        vo.setCutoff(entity.getCutoff());
//        vo.setCostStandardYear(entity.getCostStandardYear());
//        vo.setParentId(entity.getParentId());
        vo.setMark(entity.getMark());
        vo.setAuditResult(entity.getAuditResult());
        vo.setAuditTime(entity.getAuditTime());
        vo.setAuditContent(entity.getAuditContent());
        vo.setAuditUser(entity.getAuditUser());
//        vo.setSourceId(entity.getSourceId());
//        vo.setEconomicLimitYear(entity.getEconomicLimitYear());
        return vo;
    }

    /**
     * 将数据传递类转换为数据表数据类
     *
     * @param dto 数据传递类实例
     * @return 实例对象
     */
    protected ProjectReportVersion parseDTO2Entity(ProjectReportVersionDTO dto) {
        ProjectReportVersion entity = new ProjectReportVersion();
        entity.setId(dto.getId());
        entity.setName(dto.getName());
        entity.setProjectId(dto.getProjectId());
        entity.setComputeVersion(dto.getComputeVersion());
        entity.setModelId(dto.getModelId());
        entity.setBuildYearCount(dto.getBuildYearCount());
        entity.setCalculateYearStart(dto.getCalculateYearStart());
        entity.setCalculateYearEnd(dto.getCalculateYearEnd());
        entity.setRemark(dto.getRemark());
        entity.setIrrBeforeTax(dto.getIrrBeforeTax());
        entity.setIrrAfterTax(dto.getIrrAfterTax());
        entity.setPbpBeforeTax(dto.getPbpBeforeTax());
        entity.setPbpAfterTax(dto.getPbpAfterTax());
        entity.setNpvBeforeTax(dto.getNpvBeforeTax());
        entity.setNpvAfterTax(dto.getNpvAfterTax());
        entity.setCutoff(dto.getCutoff());
        entity.setParentId(dto.getParentId());
        entity.setMark(dto.getMark());
        entity.setSourceId(dto.getSourceId());
        entity.setEconomicLimitYear(dto.getEconomicLimitYear());
        return entity;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public ProjectReportVersionVO queryById(String id) {
        ProjectReportVersion entity = this.projectReportVersionDAO.selectById(id);
        if (entity == null) {
            return null;
        }
        return parseEntity2VO(entity);
    }

    /**
     * 查询多条数据
     *
     * @param dto 数据传递类实例对象
     * @return 对象列表
     */
    @Override
    public List<ProjectReportVersionVO> queryList(ProjectReportVersionQueryDTO dto) {
        //mybatis-plus 写法示例
        //IPage<ProjectReportVersion> pageResult = this.evaModelDAO.selectPage(new Page<>(dto.getPageNo(),dto.getPageSize()),null);
        //List<ProjectReportVersion> dataList = pageResult.getRecords();
        //dto.setCount((int) pageResult.getTotal());
        Set<String> filterOfficeSet = getFilterCompanySet();
        dto.setFilterOfficeSet(filterOfficeSet);
        List<ProjectReportVersionVO> dataList = this.projectReportVersionDAO.queryVOList(dto);
//        if (null == dataList || dataList.isEmpty()) {
//            return Collections.emptyList();
//        }
//        List<ProjectReportVersionVO> resultList = new ArrayList(dataList.size());
//        for (ProjectReportVersion item : dataList) {
//            ProjectReportVersionVO vo = parseEntity2VO(item);
//            resultList.add(vo);
//        }
        return dataList;
    }

    /**
     * 新增数据
     *
     * @param dto 实例对象
     * @return 操作结果
     */
    @Transactional
    @Override
    public ServiceResult create(ProjectReportVersionDTO dto) {
        // TODO 添加校验逻辑

        ComputeVersionVO computeVersion = computeVersionService.queryById(dto.getComputeVersion());
        if(computeVersion == null) {
            return CommonResultEnum.NOT_EXIST;
        }
        ProjectInfo projectInfo = projectInfoDAO.selectById(computeVersion.getProjectId());
        if(projectInfo == null) {
            return CommonResultEnum.NOT_EXIST;
        }
//        if(ProjectStateEnum.getEnum(projectInfo.getState())!=ProjectStateEnum.REPORT) {
//            return CommonResultEnum.PERMISSION_DENY;
//        }
        if(ComputeVersionTypeEnum.getEnum(computeVersion.getType())!=ComputeVersionTypeEnum.DEFAULT) {
            return CommonResultEnum.PERMISSION_DENY;
        }
        //如果有等待审核或者审核通过版本，则不能进行上报
        QueryWrapper<ProjectReportVersion> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ProjectReportVersion::getProjectId,computeVersion.getProjectId());
        ProjectReportVersionQueryDTO queryDTO = new ProjectReportVersionQueryDTO();
        queryDTO.setProjectId(computeVersion.getProjectId());
        List<ProjectReportVersionVO> reportVersionList = projectReportVersionDAO.queryVOList(queryDTO);
        if(reportVersionList!=null&&reportVersionList.size()>0) {
            for(ProjectReportVersionVO item:reportVersionList) {
                ReportAuditResultEnum auditResult = ReportAuditResultEnum.getEnum(item.getAuditResult());
                if(auditResult == ReportAuditResultEnum.AUDIT) {
                    throw new ServiceException("当前已有上报版本，无法重复上报","当前已有上报版本，无法重复上报",reportVersionList);
                }
                if(auditResult == ReportAuditResultEnum.PASS) {

                    throw new ServiceException("项目已经审核完成，无法重复审核","项目已经审核完成，无法重复审核",reportVersionList);
                }
            }
        }
        ComputeVersionDTO versionDTO = parseVersionVO2DTO(computeVersion);
        String targetType = ComputeVersionTypeEnum.REPORT.getId();
        versionDTO.setType(targetType);
        versionDTO.setReportTime(new Date());
        computeVersionService.update(versionDTO);
//        projectInfo.setState(ProjectStateEnum.AUDIT.getId());
        projectInfoDAO.updateById(projectInfo);

        ProjectReportVersion entity = parseDTO2Entity(dto);
        preInsert(entity);
        entity.setBuildYearCount(computeVersion.getBuildYearCount());
        entity.setCutoff(computeVersion.isCutoff());
        entity.setCalculateYearStart(computeVersion.getCalculateYearStart());
        entity.setCalculateYearEnd(computeVersion.getCalculateYearEnd());
//        entity.setMark(projectInfo.getExtraEvaluateMethod());
        entity.setIrrAfterTax(computeVersion.getIrrAfterTax());
        entity.setIrrBeforeTax(computeVersion.getIrrBeforeTax());
        entity.setNpvAfterTax(computeVersion.getNpvAfterTax());
        entity.setNpvBeforeTax(computeVersion.getNpvBeforeTax());
        entity.setPbpAfterTax(computeVersion.getPbpAfterTax());
        entity.setPbpBeforeTax(computeVersion.getPbpBeforeTax());
        entity.setEconomicLimitYear(computeVersion.getEconomicLimitYear());
        entity.setComputeVersion(computeVersion.getId());
        entity.setProjectId(projectInfo.getId());
        entity.setName(computeVersion.getName());
        entity.setModelId(computeVersion.getModelId());
        entity.setAuditResult(ReportAuditResultEnum.AUDIT.getId());
        this.projectReportVersionDAO.insert(entity);
        return CommonResultEnum.SUCCESS;
    }

    /**
     * 修改数据
     *
     * @param dto 实例对象
     * @return 操作结果
     */
    @Override
    public ServiceResult update(ProjectReportVersionDTO dto) {
        String id = dto.getId();
        if (StringUtils.isEmpty(id)) {
            return CommonResultEnum.NOT_EXIST;
        }
        ProjectReportVersion entity = this.projectReportVersionDAO.selectById(id);
        if (entity == null) {
            return CommonResultEnum.NOT_EXIST;
        }

        entity.setName(dto.getName());
        entity.setProjectId(dto.getProjectId());
        entity.setComputeVersion(dto.getComputeVersion());
        entity.setModelId(dto.getModelId());
        entity.setBuildYearCount(dto.getBuildYearCount());
        entity.setCalculateYearStart(dto.getCalculateYearStart());
        entity.setCalculateYearEnd(dto.getCalculateYearEnd());
        entity.setRemark(dto.getRemark());
        entity.setIrrBeforeTax(dto.getIrrBeforeTax());
        entity.setIrrAfterTax(dto.getIrrAfterTax());
        entity.setPbpBeforeTax(dto.getPbpBeforeTax());
        entity.setPbpAfterTax(dto.getPbpAfterTax());
        entity.setNpvBeforeTax(dto.getNpvBeforeTax());
        entity.setNpvAfterTax(dto.getNpvAfterTax());
        entity.setCutoff(dto.getCutoff());
        entity.setParentId(dto.getParentId());
        entity.setMark(dto.getMark());
        entity.setSourceId(dto.getSourceId());
        entity.setEconomicLimitYear(dto.getEconomicLimitYear());
        this.projectReportVersionDAO.updateById(entity);
        return CommonResultEnum.SUCCESS;
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 操作结果
     */
    @Override
    public ServiceResult deleteById(String id) {
        // TODO 添加校验逻辑，如数据权限
        this.projectReportVersionDAO.deleteById(id);
        return CommonResultEnum.SUCCESS;
    }

    @Override
    public ServiceResult deleteByProject(String projectId) {
        if(StringUtils.isEmpty(projectId)) {
            return CommonResultEnum.SUCCESS;
        }
        QueryWrapper<ProjectReportVersion> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ProjectReportVersion::getProjectId,projectId);
        projectReportVersionDAO.delete(queryWrapper);
        return CommonResultEnum.SUCCESS;
    }

    protected ComputeVersionDTO parseVersionVO2DTO(ComputeVersionVO vo) {
        if(vo == null) {
            return null;
        }
        ComputeVersionDTO dto = JSON.parseObject(JSON.toJSONString(vo),ComputeVersionDTO.class);
        return dto;
    }

    @Override
    public String getName() {
        return "项目上报版本";
    }

    @Override
    public ServiceResult handleProjectCreate(String projectId) {
        return CommonResultEnum.SUCCESS;
    }

    @Override
    public ServiceResult handleProjectDelete(String projectId) {
        return deleteByProject(projectId);
    }

    @Transactional
    @Override
    public ServiceResult audit(ProjectReportVersionDTO dto) {

        ComputeVersionVO entity = computeVersionService.queryById(dto.getComputeVersion());
        if(entity == null) {
            return CommonResultEnum.NOT_EXIST;
        }
        ProjectInfo projectInfo = projectInfoDAO.selectById(entity.getProjectId());
        if(projectInfo == null) {
            return CommonResultEnum.NOT_EXIST;
        }
//        if(ProjectStateEnum.getEnum(projectInfo.getState())!=ProjectStateEnum.AUDIT) {
//            return CommonResultEnum.PERMISSION_DENY;
//        }
        if(ComputeVersionTypeEnum.getEnum(entity.getType())!=ComputeVersionTypeEnum.REPORT) {
            return CommonResultEnum.PERMISSION_DENY;
        }
        LambdaQueryWrapper<ProjectReportVersion> queryWrapper = new LambdaQueryWrapper<ProjectReportVersion>();
        queryWrapper.eq(ProjectReportVersion::getComputeVersion,entity.getId());
        queryWrapper.eq(ProjectReportVersion::getProjectId,entity.getProjectId());
        ProjectReportVersion reportVersion = projectReportVersionDAO.selectOne(queryWrapper);
        if(reportVersion == null) {
            return CommonResultEnum.NOT_EXIST;
        }
        ComputeVersionDTO versionDTO = parseVersionVO2DTO(entity);
        if(dto.isPass()) {
            versionDTO.setType(ComputeVersionTypeEnum.FINAL.getId());
//            projectInfo.setState(ProjectStateEnum.COMPLETE.getId());
            reportVersion.setAuditResult(ReportAuditResultEnum.PASS.getId());
        } else {
            versionDTO.setType(ComputeVersionTypeEnum.BACK.getId());
//            projectInfo.setState(ProjectStateEnum.REPORT.getId());
            reportVersion.setAuditResult(ReportAuditResultEnum.REJECT.getId());
        }
        computeVersionService.update(versionDTO);
        projectInfoDAO.updateById(projectInfo);
        reportVersion.setAuditTime(new Date());
        reportVersion.setAuditContent(dto.getAuditContent());
        reportVersion.setAuditUser(getUserId());
        projectReportVersionDAO.updateById(reportVersion);
        return CommonResultEnum.SUCCESS;
    }
}
